package dyyx.demo;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;

import javax.sound.midi.SysexMessage;

import org.h2.mvstore.Cursor;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.MVStore;

import dyyx.util.CommUtil;

/**
 * 并发读写  
 * 
 * @author dugang
 *
 */
public class MVStoreReadWriteTest {

	private static final int num = CommUtil.getNumFromSysProp();

	private static final Random rand = new Random();

	private static volatile String writeErrorMsg = null;
	private static volatile String readErrorMsg = null;
	
	private static final AtomicLong writeCount = new AtomicLong(0);
	private static final AtomicLong readCount = new AtomicLong(0);
	
	public static void main(String[] args) throws Exception {
		System.out.println("hello,MVStoreReadWriteTest," + new Date());

		String home = CommUtil.getUserHome();
		System.out.println("home="+home);
		String fileName = home+"/h2/001.data";
		
		// java.lang.IllegalArgumentException: Directory does not exist:
		// nio:/Users/dugang/h2 [1.4.200/0]
		MVStore s = MVStore.open(fileName);

		MVMap<Integer, String> map = s.openMap("data");
		System.out.println("num=" + num);

		WriteThread writeThread = new WriteThread(map);
		writeThread.setName("writeThread");
		writeThread.start();

		ReadThread readThread = new ReadThread(map);
		readThread.setName("readThread");
		readThread.start();

		while (true) {

			Thread.sleep(1000);

			System.out.println(getInfo());

		}

	}

	private static Map getInfo() {
		Map map = new LinkedHashMap();
		//map.put("time", System.currentTimeMillis());
		map.put("writeCount", writeCount);
		map.put("readCount", readCount);
		
		map.put("writeErrorMsg", writeErrorMsg);
		map.put("readErrorMsg", readErrorMsg);
	
		return map;
	}

	private static class WriteThread extends Thread {

		final MVMap<Integer, String> map;

		public WriteThread(MVMap<Integer, String> map) {
			this.map = map;
		}

		public void run() {

			while (true) {

				try {
					int key = rand.nextInt(num);
					map.put(key, key + "_" + LocalDateTime.now());
					writeCount.getAndIncrement();
				} catch (Throwable e) {
					writeErrorMsg = e.toString();
					break;
				}

			}

		}
	}

	private static class ReadThread extends Thread {

		final MVMap<Integer, String> map;

		public ReadThread(MVMap<Integer, String> map) {
			this.map = map;
		}

		public void run() {
			while (true) {

				try {
					int key = rand.nextInt(num);
					map.get(key);
					readCount.getAndIncrement();

				} catch (Throwable e) {
					writeErrorMsg = e.toString();
					break;
				}
			}

		}
	}

	

}
